﻿using Module.FlowChart.Model;
using Module.FlowChart.RunAble.View;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Windows.Forms;

namespace Module.FlowChart.View
{
    internal partial class Form_FlowChart : Form
    {
        static public Form_FlowChart MainForm;


        public object ActionLocker { get; private set; } = new object();
        public Action Actions { get; internal set; } = () => { };

        Size ChartSmallIconSize;

        public Document Document;
        Dictionary<string, ViewManager> ViewManagers;
        public ViewManager CurrentViewManager { get; private set; }


        public Form_FlowChart()
        {
            InitializeComponent();
            MainForm = this;


            ViewManagers = new Dictionary<string, ViewManager>() { };
            #region initdoc
            Document doc1 = Document = new Document();
            CreatNewPage(RunAbleFCWorkPage.TypeNameS);
            OnOpenOrCreatDocument(doc1);
            #endregion


            #region 菜单事件绑定
            Menu_About.Click += (s, e) => { MessageBox.Show("这是一个测试版本", "提示"); };
            Menu_Flie_New_NewDoc.Click += (s, e) =>
            {
                Document doc = Document = new Document();
                string typename = Form_CreatePage.ShowWindow();
                CreatNewPage(typename);
                OnOpenOrCreatDocument(doc);
            };

            Menu_File_New_NewPage.Click += (s, e) =>
            {
                string typename = Form_CreatePage.ShowWindow();
                if (typename != "")
                {
                    TabPage v;
                    (v, _) = CreatNewPage(typename);
                    SelectPage(WorkPages.TabPages.Count - 1);
                }
            };

            Menu_File_Save.Click += (s, e) => { Save(); };
            Menu_File_Load.Click += (s, e) => { LoadDoc(); };

            Menu_PageEditor.Click += (s, e) =>
            {
                if (Document == null)
                {
                    MessageBox.Show("没有创建工作簿", "提示");
                    return;
                }
                ShowPageEditor();
            };
            #endregion

            Form_FlowChart_ResizeEnd(null, null);
        }

        void OnOpenOrCreatDocument(Document doc)
        {
            WorkPages.TabPages.Clear();
            if (ViewManagers != null)
            {
                foreach (var item in ViewManagers.Values)
                {
                    item.SetActive(false);
                    item.DestoryMgr();
                }
            }

            ViewManagers = new Dictionary<string, ViewManager>();
            foreach (var page in doc.WorkPages)
            {
                var pageview = new TabPage();
                WorkPages.TabPages.Add(pageview);
                pageview.Text = page.Name;
                GetorCreateViewManager(page, pageview);
            }
            if (doc.WorkPages.Count > 0)
            {
                Document.SetCurrentWorkPage(WorkPages.TabPages[0].Text);
                CurrentViewManager = GetorCreateViewManager(doc.CurrentWorkPage, WorkPages.TabPages[0]);
                WorkPages.SelectedIndex = 0;
                CurrentViewManager.SetActive(true);
            }
        }
        (TabPage, WorkPage) CreatNewPage(string pagetype = "")
        {
            pagetype = pagetype == "" ? WorkPage.DefaultPageType : pagetype;
            var page = Document.CreatWorkPage(pagetype);
            var pageview = new TabPage();
            WorkPages.TabPages.Add(pageview);
            pageview.Text = page.Name;
            return (pageview, page);
        }
        ViewManager GetorCreateViewManager(WorkPage page, TabPage view)
        {
            if (ViewManagers.ContainsKey(view.Text))
            {
                return ViewManagers[view.Text];
            }
            if (page.TypeName == RunAbleFCWorkPage.TypeNameS)
            {
                var t = new ViewManager_Code(GetViewManagerHandles(), Document, page as RunAbleFCWorkPage, view);
                ViewManagers.Add(page.Name, t);
                return t;
            }
            else if (page.TypeName == SequentialFCWorkPage.TypeNameS)
            {
                var t = new ViewManager_Sequential(GetViewManagerHandles(), Document, page as SequentialFCWorkPage, view);
                ViewManagers.Add(page.Name, t);
                return t;
            }
            else if (page.TypeName == TextWorkPage.TypeNameS)
            {
                var t = new ViewManager_Text(GetViewManagerHandles(), Document, page as TextWorkPage, view);
                ViewManagers.Add(page.Name, t);
                return t;
            }
            return null;
        }


        ViewManagerHandles ViewManagerHandles;
        Control RightWindow;
        ViewManagerHandles GetViewManagerHandles()
        {
            if (ViewManagerHandles != null)
            {
                return ViewManagerHandles;
            }

            var h = new ViewManagerHandles();
            h.GetDocument = () => { return Document; };
            h.AddMenu = (m) =>
            {
                menuStrip1.Items.Insert(menuStrip1.Items.Count - 1, m);
            };
            h.ChangePage = (name) => { SetPage(name); };
            h.GetControl = (name) =>
            {
                switch (name)
                {
                    case "chartCandidateList":
                        return ChartCandidateList;
                    default:
                        break;
                }
                return null;
            };
            h.Drawed = () => { textBox1.Text = textBox1.Text == "" ? "1" : "" + (int.Parse(textBox1.Text) + 1); };
            h.SetRightForm = (form, show) =>
            {
                if (show)
                {
                    if (RightWindow != null)
                    {
                        throw new Exception("右窗口已经存在");
                    }
                    RightWindow = form;
                    form.Parent = splitContainer2.Panel2;
                    form.Dock = DockStyle.Fill;
                    SetSp2Size();
                }
                else
                {
                    if (RightWindow != form)
                    {
                        throw new Exception("右窗口隐藏失败");
                    }
                    RightWindow = null;
                    form.Parent = null;
                    form.Dock = DockStyle.None;
                    SetSp2Size();
                }

            };
            h.GetRightWindow = () =>
            {
                return RightWindow;
            };
            ViewManagerHandles = h;
            return h;
        }

        Form_PageEditor pageEditor;
        private void ShowPageEditor()
        {
            if (pageEditor == null)
            {
                pageEditor = new Form_PageEditor(new Form_PageEditor.PageNameEditor_Handles
                {
                    ChangeName = (name, nname) =>
                    {
                        if (Document == null)
                            return false;
                        var page = Document.TryGetPage(name);
                        if (page == null)
                            return false;
                        page.Name = nname;
                        foreach (TabPage item in WorkPages.TabPages)
                        {
                            if (item.Text == name)
                            {
                                item.Text = nname;
                                break;
                            }
                        }
                        var mgr = ViewManagers[name];
                        mgr.OnPageNameChanged(name, nname);
                        ViewManagers.Remove(name);
                        ViewManagers[nname] = mgr;
                        return true;
                    },
                    DeletPage = (name) =>
                    {
                        if (Document == null)
                            return false;
                        bool r = Document.RemovePage(name);
                        if (r == false)
                            return false;
                        if (ViewManagers[name].Active)
                            ViewManagers[name].SetActive(false);
                        ViewManagers.Remove(name);
                        for (int i = 0; i < WorkPages.TabPages.Count; i++)
                        {
                            if (WorkPages.TabPages[i].Text == name)
                            {
                                WorkPages.TabPages.RemoveAt(i);
                                break;
                            }
                        }
                        return true;
                    },
                    MoveUp = (name) =>
                    {
                        if (Document == null)
                            return false;
                        var r = Document.MoveUp(name);
                        if (!r)
                            throw new Exception();
                        for (int i = 0; i < WorkPages.TabPages.Count; i++)
                        {
                            if (WorkPages.TabPages[i].Text == name)
                            {
                                var t = WorkPages.TabPages[i - 1];
                                WorkPages.TabPages[i - 1] = WorkPages.TabPages[i];
                                WorkPages.TabPages[i] = t;
                                if (WorkPages.SelectedIndex == i)
                                {
                                    SelectPage(i - 1);
                                }
                                else if (WorkPages.SelectedIndex == i - 1)
                                {
                                    SelectPage(i);
                                }
                                break;
                            }
                        }
                        return true;
                    },
                    MoveDown = (name) =>
                    {
                        if (Document == null)
                            return false;
                        var r = Document.MoveDown(name);
                        if (!r)
                            throw new Exception();
                        for (int i = 0; i < WorkPages.TabPages.Count; i++)
                        {
                            if (WorkPages.TabPages[i].Text == name)
                            {
                                var t = WorkPages.TabPages[i + 1];
                                WorkPages.TabPages[i + 1] = WorkPages.TabPages[i];
                                WorkPages.TabPages[i] = t;
                                if (WorkPages.SelectedIndex == i)
                                {
                                    SelectPage(i + 1);
                                }
                                else if (WorkPages.SelectedIndex == i + 1)
                                {
                                    SelectPage(i);
                                }
                                break;
                            }
                        }
                        return true;
                    },
                    GetPageItems = () =>
                    {
                        if (Document == null)
                            return null;
                        return Document.WorkPages.Select((e) => { return e.Name; }).ToList();
                    },
                    CreatNewPage = (typename) =>
                    {
                        if (typename != "")
                        {
                            TabPage v;
                            (v, _) = CreatNewPage(typename);
                            SelectPage(WorkPages.TabPages.Count - 1);
                        }
                        return true;
                    }
                });
            }
            pageEditor.BeforShow();
            pageEditor.ShowDialog();
        }


        void Save()
        {
            BinaryWriter bw = null;
            string path;
            if (Document.Path == "")
            {
                SaveFileDialog fbd = new SaveFileDialog();
                fbd.Filter = "FlowChart|*" + Document.DocExtension;// "Excel|*.xls;*.xlsx;";
                fbd.Title = "保存为"; ;
                var dre = fbd.ShowDialog();
                if (dre == DialogResult.OK)
                {
                    path = fbd.FileName;
                }
                else
                {
                    return;
                }
            }
            else
            {
                path = Document.Path;
            }

            // 创建文件
            try
            {
                bw = new BinaryWriter(new FileStream(path, FileMode.Create));
                Document.Save(bw);
            }
            catch
            {
                return;
            }
            finally
            {
                bw.Close();
                Document.Path = path;
            }
        }
        void LoadDoc()
        {
            if (Document != null && Document.GetIsChanged())
            {
                DialogResult res = MessageBox.Show("当前文档已修改，是否保存", "提示", MessageBoxButtons.YesNoCancel);
                if (res == DialogResult.Yes)
                {
                    //保存
                    Save();
                }
                else if (res == DialogResult.No)
                {
                    //不保存
                }
                else
                {
                    //取消
                    return;
                }
            }
            BinaryReader br = null;
            string path = "";
            OpenFileDialog obd = new OpenFileDialog();
            obd.Filter = "FlowChart|*" + Document.DocExtension;// "Excel|*.xls;*.xlsx;";
            obd.Title = "加载"; ;
            var dre = obd.ShowDialog();
            if (dre == DialogResult.OK)
            {
                path = obd.FileName;
            }
            else
            {
                return;
            }
            try
            {
                br = new BinaryReader(new FileStream(path, FileMode.Open));
                Document.Path = path;
                Document = Document.LoadFromBytes(br);
                OnOpenOrCreatDocument(Document);
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
                return;
            }
            finally
            {
                br?.Close();
            }
        }

        /// <summary>
        /// 设置当前显示的页
        /// </summary>
        public void SetPage(string pagename)
        {
            for (int i = 0; i < WorkPages.TabPages.Count; i++)
            {
                var page = WorkPages.TabPages[i];
                if (page.Text == pagename)
                {
                    SelectPage(i);
                    return;
                }
            }
            Debugger.Assert("页名称应该在WorkPages中");
        }
        private void SelectPage(int index)
        {
            var page = WorkPages.TabPages[index];
            Document.SetCurrentWorkPage(page.Text);
            CurrentViewManager?.SetActive(false);
            (CurrentViewManager = GetorCreateViewManager(Document.TryGetPage(page.Text), page)).SetActive(true);
            WorkPages.SelectedIndex = index;
        }



        private void tevery33ms(object sender, EventArgs e)
        {
            if (CurrentViewManager == null)
                return;
            CurrentViewManager.Every33ms();
        }


        private void Form_FlowChart_SizeChanged(object sender, EventArgs e)
        {
            SetSp2Size();
            if (ViewManagerHandles == null || ViewManagerHandles.IsResizing)
                return;
            Form_FlowChart_ResizeEnd(null, null);
        }
        private void Form_FlowChart_ResizeBegin(object sender, EventArgs e)
        {
            ViewManagerHandles.IsResizing = true;
        }
        private void Form_FlowChart_ResizeEnd(object sender, EventArgs e)
        {
            ViewManagerHandles.IsResizing = false;
            if (WindowState == FormWindowState.Minimized)
                return;

            CurrentViewManager?.Resized();

        }

        private void SetSp2Size()
        {
            if (RightWindow == null)
            {
                splitContainer2.SplitterDistance = (int)(splitContainer2.Size.Width * 0.95f);
            }
            else
            {
                splitContainer2.SplitterDistance = (int)(splitContainer2.Size.Width * 0.85f);
            }
        }

        private void WorkPages_MouseDown(object sender, MouseEventArgs e)
        {
            for (int i = 0; i < WorkPages.TabPages.Count; i++)
            {
                if (WorkPages.GetTabRect(i).Contains(e.Location))
                {
                    SelectPage(i);
                    return;
                }
            }
        }

        private void splitContainer1_Panel1_Paint(object sender, PaintEventArgs e)
        {

        }

        private void splitContainer1_Panel2_Paint(object sender, PaintEventArgs e)
        {

        }
    }
}
